﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CH.Easy.DbProvider.Interface;
using CH.Easy.DbProvider.Entity;
using System.Runtime.Remoting;
using System.Data;
using CH.Easy.DbProvider.Common;
using System.Data.Common;
using System.Linq.Expressions;

namespace CH.Easy.DbProvider.Core
{
    public static class DbTableExtend
    {



        public static QueryResult<T> ToPList<T>(this IQueryable<T> source)
        {
            IQueryable p = (IQueryable)Activator.CreateInstance(typeof(DbTable<>).MakeGenericType(typeof(QueryResult<>).MakeGenericType(typeof(T))), new object[] { source.Provider, source.Expression });
            return (QueryResult<T>)p.Provider.Execute(p.Expression);
        }

        public static TEntity GetByFilter<TEntity>(this IDbTable<TEntity> table, Expression<Func<TEntity, bool>> filter)
        {
            return table.Where(filter).Select(p => p).ToList().FirstOrDefault();
        }

        public static TResult GetByFilter<TEntity, TResult>(this IDbTable<TEntity> table, Expression<Func<TEntity, bool>> filter, Expression<Func<TEntity, TResult>> selector)
        {
            return table.Where(filter).Select(selector).ToList().FirstOrDefault();
        }

        public static List<TEntity> GetAll<TEntity>(this IDbTable<TEntity> table)
        {
            return table.Select(p => p).ToList();

        }

        public static QueryResult<TEntity> GetListByPage<TEntity>(this IDbTable<TEntity> table, int pageIndex, int pageSize)
        {
            return table.Select(p => p).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToPList();

        }

        public static QueryResult<TEntity> GetListByPage<TEntity>(this IDbTable<TEntity> table, int pageIndex, int pageSize, Expression<Func<TEntity, bool>> filter)
        {
            return table.Where(filter).Select(p => p).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToPList();

        }

        public static QueryResult<TResult> GetListByPage<TEntity, TResult>(this IDbTable<TEntity> table, int pageIndex, int pageSize, Expression<Func<TEntity, bool>> filter, Expression<Func<TEntity, TResult>> selector)
        {
            return table.Where(filter).Skip((pageIndex - 1) * pageSize).Take(pageSize).Select(selector).ToPList();
        }

        public static QueryResult<TResult> GetListByPage<TEntity, TResult, TKey>(this IDbTable<TEntity> table, int pageIndex, int pageSize, Expression<Func<TEntity, bool>> filter, Expression<Func<TEntity, TResult>> selector, Expression<Func<TEntity, TKey>> orderByExpression, bool ascending)
        {
            QueryResult<TResult> result = null;
            if (ascending)
            {
                result = table.Where(filter).OrderBy(orderByExpression).Skip((pageIndex - 1) * pageSize).Take(pageSize).Select(selector).ToPList();
            }
            else
            {
                result = table.Where(filter).OrderByDescending(orderByExpression).Skip((pageIndex - 1) * pageSize).Take(pageSize).Select(selector).ToPList();

            }
            return result;
        }

        public static List<TEntity> GetListByFilter<TEntity>(this IDbTable<TEntity> table, Expression<Func<TEntity, bool>> filter)
        {
            return table.Where(filter).Select(p => p).ToList();
        }

        public static List<TResult> GetListByFilter<TEntity, TResult>(this IDbTable<TEntity> table, Expression<Func<TEntity, bool>> filter, Expression<Func<TEntity, TResult>> selector)
        {
            return table.Where(filter).Select(selector).ToList();
        }

        public static List<TResult> GetListByFilter<TEntity, TResult, TKey>(this IDbTable<TEntity> table, Expression<Func<TEntity, bool>> filter, Expression<Func<TEntity, TResult>> selector, Expression<Func<TEntity, TKey>> orderByExpression, bool ascending)
        {
            List<TResult> list = null;
            if (ascending)
            {
                list = table.Where(filter).OrderBy(orderByExpression).Select(selector).ToList();
            }
            else
            {
                list = table.Where(filter).OrderByDescending(orderByExpression).Select(selector).ToList();

            }
            return list;
        }






    }
}
